/*!
 * \file scheduling_policies.hpp
 * \brief 任务调度策略
 *
 * \details 此文件包含pool类的一些基本调度策略。
 *          
 *          调度策略通过任务容器实现，控制对任务的访问。从根本上说，
 *          容器决定了线程池处理任务的顺序。
 *          
 *          任务容器不需要是线程安全的，因为它们被池以线程安全的
 *          方式使用。
 *          
 *          提供的调度策略包括：
 *          - FIFO调度器：先进先出调度
 *          - LIFO调度器：后进先出调度
 *          - 优先级调度器：基于任务优先级的调度
 *          
 *          这些调度策略为不同的应用场景提供了灵活的任务执行顺序控制。
 *
 * Copyright (c) 2005-2007 Philipp Henkel
 *
 * Use, modification, and distribution are  subject to the
 * Boost Software License, Version 1.0. (See accompanying  file
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 *
 * http://threadpool.sourceforge.net
 *
 */

#ifndef THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED
#define THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED

#include <queue>
#include <deque>

#include "task_adaptors.hpp"

namespace boost { namespace threadpool
{

  /*!
   * \brief 实现FIFO排序的调度策略
   *
   * \details 此容器实现FIFO调度策略。
   *          添加到调度器的第一个任务将是第一个被移除的任务。
   *          处理按相同顺序依次进行。
   *          FIFO代表"先进先出"。
   *          
   *          适用场景：
   *          - 需要严格按时间顺序处理任务
   *          - 公平调度，避免任务饥饿
   *          - 批处理作业的顺序执行
   *
   * \tparam Task 实现operator()(void)的函数对象类型
   */ 
  template <typename Task = task_func>  
  class fifo_scheduler
  {
  public:
    typedef Task task_type; //!< 指示调度器的任务类型

  protected:
    std::deque<task_type> m_container;  //!< 内部任务容器

  public:
    /*!
     * \brief 向调度器添加新任务
     * \param task 任务对象
     * \return 如果任务可以被调度则返回true，否则返回false
     */
    bool push(task_type const & task)
    {
      m_container.push_back(task);
      return true;
    }

    /*!
     * \brief 移除下一个应该执行的任务
     */
    void pop()
    {
      m_container.pop_front();
    }

    /*!
     * \brief 获取下一个应该执行的任务
     * \return 要执行的任务对象
     */
    task_type const & top() const
    {
      return m_container.front();
    }

    /*!
     * \brief 获取调度器中当前的任务数量
     * \return 任务数量
     * \remarks 推荐使用empty()而不是size() == 0来检查调度器是否为空
     */
    size_t size() const
    {
      return m_container.size();
    }

    /*!
     * \brief 检查调度器是否为空
     * \return 如果调度器不包含任务则返回true，否则返回false
     * \remarks 比size() == 0更高效
     */
    bool empty() const
    {
      return m_container.empty();
    }

    /*!
     * \brief 从调度器中移除所有任务
     */  
    void clear()
    {   
      m_container.clear();
    } 
  };

  /*!
   * \brief 实现LIFO排序的调度策略
   *
   * \details 此容器实现LIFO调度策略。
   *          最后添加到调度器的任务将是第一个被移除的任务。
   *          LIFO代表"后进先出"。
   *          
   *          适用场景：
   *          - 栈式任务处理
   *          - 递归算法的任务分解
   *          - 需要处理最新任务的场景
   *
   * \tparam Task 实现operator()(void)的函数对象类型
   */ 
  template <typename Task = task_func>  
  class lifo_scheduler
  {
  public:
    typedef Task task_type;  //!< 指示调度器的任务类型

  protected:
    std::deque<task_type> m_container;  //!< 内部任务容器

  public:
    /*!
     * \brief 向调度器添加新任务
     * \param task 任务对象
     * \return 如果任务可以被调度则返回true，否则返回false
     */
    bool push(task_type const & task)
    {
      m_container.push_front(task);
      return true;
    }

    /*!
     * \brief 移除下一个应该执行的任务
     */
    void pop()
    {
      m_container.pop_front();
    }

    /*!
     * \brief 获取下一个应该执行的任务
     * \return 要执行的任务对象
     */
    task_type const & top() const
    {
      return m_container.front();
    }

    /*!
     * \brief 获取调度器中当前的任务数量
     * \return 任务数量
     * \remarks 推荐使用empty()而不是size() == 0来检查调度器是否为空
     */
    size_t size() const
    {
      return m_container.size();
    }

    /*!
     * \brief 检查调度器是否为空
     * \return 如果调度器不包含任务则返回true，否则返回false
     * \remarks 比size() == 0更高效
     */
    bool empty() const
    {
      return m_container.empty();
    }

    /*!
     * \brief 从调度器中移除所有任务
     */  
    void clear()
    {    
      m_container.clear();
    } 
  };

  /*!
   * \brief 实现优先级排序的调度策略
   *
   * \details 此容器实现基于任务优先级的调度策略。
   *          具有最高优先级的任务将是第一个被移除的任务。
   *          必须能够使用operator<比较两个任务。
   *          
   *          适用场景：
   *          - 需要区分任务重要性的系统
   *          - 实时系统的任务调度
   *          - 资源受限环境下的优先级处理
   *
   * \tparam Task 实现operator()和operator<的函数对象类型。operator<必须是偏序关系
   *
   * \see prio_task_func
   */ 
  template <typename Task = prio_task_func>  
  class prio_scheduler
  {
  public:
    typedef Task task_type; //!< 指示调度器的任务类型

  protected:
    std::priority_queue<task_type> m_container;  //!< 内部任务容器

  public:
    /*!
     * \brief 向调度器添加新任务
     * \param task 任务对象
     * \return 如果任务可以被调度则返回true，否则返回false
     */
    bool push(task_type const & task)
    {
      m_container.push(task);
      return true;
    }

    /*!
     * \brief 移除下一个应该执行的任务
     */
    void pop()
    {
      m_container.pop();
    }

    /*!
     * \brief 获取下一个应该执行的任务
     * \return 要执行的任务对象
     */
    task_type const & top() const
    {
      return m_container.top();
    }

    /*!
     * \brief 获取调度器中当前的任务数量
     * \return 任务数量
     * \remarks 推荐使用empty()而不是size() == 0来检查调度器是否为空
     */
    size_t size() const
    {
      return m_container.size();
    }

    /*!
     * \brief 检查调度器是否为空
     * \return 如果调度器不包含任务则返回true，否则返回false
     * \remarks 比size() == 0更高效
     */
    bool empty() const
    {
      return m_container.empty();
    }

    /*!
     * \brief 从调度器中移除所有任务
     */  
    void clear()
    {    
      while(!m_container.empty())
      {
        m_container.pop();
      }
    } 
  };

} } // namespace boost::threadpool

#endif // THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED

